package com.markul.android.ui.main

import android.Manifest
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.MotionEvent
import android.view.View
import android.widget.Toast
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import com.baidu.location.*
import com.permissionx.guolindev.PermissionX
import kotlinx.android.synthetic.main.activity_main.*
import com.markul.android.logic.room.User
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import com.baidu.mapapi.map.*
import com.baidu.mapapi.model.LatLng
import com.baidu.mapapi.map.MarkerOptions
import com.baidu.mapapi.map.OverlayOptions
import com.baidu.mapapi.map.BitmapDescriptorFactory
import com.baidu.mapapi.map.MapStatusUpdateFactory
import com.baidu.mapapi.map.BaiduMap
import com.baidu.mapapi.map.MapView
import com.baidu.mapapi.search.poi.*
import kotlinx.android.synthetic.main.activity_mark.*
import java.util.*
import com.markul.android.logic.model.Repository
import com.baidu.mapapi.map.Marker
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener
import com.baidu.mapapi.map.BaiduMap.OnMarkerDragListener
import com.google.android.material.tabs.TabLayout
import com.markul.android.*
import com.markul.android.R
import com.markul.android.ui.UiTool
import com.markul.android.ui.detail.DetailedActivity
import com.markul.android.ui.dialog.DialogActivity
import com.markul.android.ui.main.mainFragment.MyMainFragment
import com.markul.android.ui.main.mainFragment.OurMainFragment
import com.markul.android.ui.shared.CreatemapActivity
import kotlinx.android.synthetic.main.activity_main.view.*


class MainActivity : AppCompatActivity() {
    var handler = Handler()
    val user = User("13664926021", "123", "123")
    lateinit var tabLayout: TabLayout

    // 地图View实例
    private var mLocClient: LocationClient? = null
    val myListener = MyLocationListener()
    var mMapView: MapView? = null
    var mBaiduMap: BaiduMap? = null

    // 用于设置个性化地图的样式文件
    private val CUSTOM_FILE_NAME_CX = "custom_map_config_CX.sty"

    // 是否首次定位
    var isFirstLoc = true

    val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        tabLayout = findViewById(R.id.MainTab)
        var tab1: TabLayout.Tab? = tabLayout.getTabAt(0)
        var tab2: TabLayout.Tab? = tabLayout.getTabAt(1)
        tab1!!.view.setOnClickListener {
            replaceFragment(MyMainFragment())
        }
        tab2!!.view.setOnClickListener {
            replaceFragment(OurMainFragment())
        }

//        //观察现在的公共空间的公共相册数量
//        Repository.allPAlbums.observe(this, {
//
//        })

        // 设置隐藏状态栏和导航栏
        UiTool.hideStatusNavigationBar(this, true)

        viewModel.addUser(user)
        //提醒用户授权
        checkPermission()
        //观察数据变化
        Repository.allAlbums.observe(this, { it ->
            //观察现在的相册数量
            if (it.isNotEmpty()) {
                var maxId = 0
                for (i in it.indices) {
                    Log.i("12345", "indices ${it.indices}")
                    if (maxId < it[i].albumId + 1) {
                        maxId = it[i].albumId + 1
                    }
                }
                if (MarkulApplication.albumMaxId < maxId) {
                    MarkulApplication.albumMaxId = maxId
                }
                Log.i("12345", "max ${MarkulApplication.albumMaxId}")
            }
            if (MarkulApplication.load) {
                MarkulApplication.load = false
                Repository.allAlbum.observe(this, { Album ->
                    if (Album.isNotEmpty()) {
                        var point = LatLng(
                            Album[0].lat,
                            Album[0].lng
                        )
                        setCenter(point)
                        Toast.makeText(this, "删除成功!", Toast.LENGTH_LONG).show()
                        val handler1 = Handler()
                        val handler2 = Handler()
                        //设置延时让画面先加载好
                        handler1.postDelayed(
                            Runnable {
                                addMarker(point, Album[0].albumIcon1, Album[0].albumId)
                                Log.i("123456", "iocn id ${Album[0].albumIcon1}")
                            }, 1000
                        )
                        //设置延时让画面回到定位点
                        handler2.postDelayed(
                            Runnable {
                                setCenter(LatLng(23.0540551376, 113.4130708748))
                            }, 5000
                        )
                    }
                })
            } else {
                mBaiduMap!!.clear()
                for (i in it) {
                    //同步已删除的内容
                    if (MarkulApplication.delId != -1) {
                        viewModel.markerList.clear()
                        viewModel.albumIdList.clear()
                        var latlng = LatLng(i.lat, i.lng)
                        addMarker(latlng, i.albumIcon1, i.albumId)
                        setCenter(LatLng(23.0540551376, 113.4130708748))
                        MarkulApplication.delId = -1
                    }

                }
            }
        })
        //地图初始化
        mMapView = findViewById<View>(R.id.bmapView) as MapView
        mBaiduMap = mMapView!!.map
        // 定义点聚合管理类ClusterManager
//        var mClusterManager = ClusterManager<MyItem>(this, mBaiduMap)
        //改变地图样式
        changeMapStyle()
        //改变定位图标
        changeLocationIcon()
        //初始化定位
        initLocation()

//        shareMapBtn.setOnClickListener{
//            val intent = Intent(this, ShareMap::class.java)
//            startActivity(intent)
//        }
        addMapBtn.setOnClickListener {
            startActivity<CreatemapActivity>(this) {}
        }
    }

    //确认用户权限许可
    private fun checkPermission() {
        PermissionX.init(this)
            .permissions(
                Manifest.permission.INTERNET,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_FINE_LOCATION,
//                Manifest.permission.ACCESS_MEDIA_LOCATION
//                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.ACCESS_COARSE_LOCATION
//                Manifest.permission.READ_CONTACTS

            )
            .onExplainRequestReason { scope, deniedList, beforeRequest ->
                scope.showRequestReasonDialog(
                    deniedList,
                    "即将重新申请的权限是必须依赖的权限,否则无法正常使用应用",
                    "我已明白",
                    "取消"
                )
            }
            .onForwardToSettings { scope, deniedList ->
                scope.showForwardToSettingsDialog(deniedList, "您需要去应用程序设置当中手动开启权限", "确定", "取消")
            }
            .request { allGranted, grantedList, deniedList ->
                if (allGranted) {
                    Toast.makeText(this, "所有权限都已经通过", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(this, "您拒绝了如下权限：$deniedList", Toast.LENGTH_SHORT).show()
                }
            }
    }

    //增加打卡点
    private fun addMarker(point: LatLng, picId: Int?, albumId: Int) {
        //构建Marker图标
        var bitmap: BitmapDescriptor
        if (picId == null) {
            bitmap = BitmapDescriptorFactory
                .fromResource(MarkulApplication.headImage)
        } else {
            bitmap = BitmapDescriptorFactory
                .fromResource(picId)
        }
        //构建MarkerOption，用于在地图上添加Marker
        val option: OverlayOptions = MarkerOptions()
            .position(point)
            .icon(bitmap)
            .perspective(true)
            .animateType(MarkerOptions.MarkerAnimateType.grow)
            .draggable(true)
        //在地图上添加Marker，并显示
        viewModel.markerList.add((mBaiduMap!!.addOverlay(option)) as Marker)
        viewModel.albumIdList.add(albumId)
        //对 marker 添加点击相应事件
        mBaiduMap!!.setOnMarkerClickListener(OnMarkerClickListener {
            var size = 1
            for (i in 0 until viewModel.markerList.size) {
                if (it == viewModel.markerList[i] && !MarkulApplication.isStartNewAcitity) {
                    Repository.allPhotos.observe(this, { Album ->
                        size = Album[i].photoList.size
                    })
                    val intent = Intent(this, DetailedActivity::class.java)
                    if (size == 1) {
                        intent.putExtra("number", "only")
                        intent.putExtra("position", i)
                    } else {
                        intent.putExtra("number", "more")
                        intent.putExtra("position", i)
                    }
                    MarkulApplication.isStartNewAcitity = true
                    startActivity(intent)
                }
            }
            false
        })
        mBaiduMap!!.setOnMarkerDragListener(object : OnMarkerDragListener {
            //在Marker拖拽过程中回调此方法，这个Marker的位置可以通过getPosition()方法获取
            //marker 被拖动的Marker对象
            override fun onMarkerDrag(marker: Marker) {
            }


            override fun onMarkerDragEnd(marker: Marker) {}

            //在Marker开始被拖拽时回调此方法， 这个Marker的位可以通过getPosition()方法获取
            //marker 被拖拽的Marker对象
            override fun onMarkerDragStart(marker: Marker) {
                for (i in 0 until viewModel.markerList.size) {
                    if (marker == viewModel.markerList[i]) {
                        val intent = Intent(MarkulApplication.context, DialogActivity::class.java)
                        intent.putExtra("number", "only")
                        intent.putExtra("position", viewModel.albumIdList[i])
                        startActivity(intent)
                    }
                }
            }
        })
    }

    //设置地图中心
    private fun setCenter(point: LatLng) {
        //设定中心点坐标
        //定义地图状态
        val mMapStatus: MapStatus = MapStatus.Builder()
            .target(point)
            .zoom(15.0f)
            .build()
        //定义MapStatusUpdate对象，以便描述地图状态将要发生的变化
        val mMapStatusUpdate = MapStatusUpdateFactory
            .newMapStatus(mMapStatus)
        //改变地图状态
        mBaiduMap!!.setMapStatus(mMapStatusUpdate)
    }

    //改变地图主题
    private fun changeMapStyle() {
        // 构建地图状态
        val builder = MapStatus.Builder()
        // 更新地图
        mMapView!!.map.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()))
        // 获取.sty文件路径
        val customStyleFilePath: String? =
            getCustomStyleFilePath(this@MainActivity, CUSTOM_FILE_NAME_CX)
        // 设置个性化地图样式文件的路径和加载方式
        mMapView!!.setMapCustomStylePath(customStyleFilePath)
        // 动态设置个性化地图样式是否生效
        mMapView!!.setMapCustomStyleEnable(true)
    }

    //改变定位图标样式
    private fun changeLocationIcon() {
        val mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL
        val accuracyCircleFillColor = -0x55000078
        val accuracyCircleStrokeColor = 0x55ff0100
        //修改为自定义图层
        var mcurrentMarker = BitmapDescriptorFactory.fromResource(MarkulApplication.headImage)
        mBaiduMap!!.setMyLocationConfiguration(
            MyLocationConfiguration(
                mCurrentMode, true, mcurrentMarker,
                accuracyCircleFillColor, accuracyCircleStrokeColor
            )
        )
    }

    //加载定位
    private fun initLocation() {
        // 开启定位图层
        mBaiduMap!!.isMyLocationEnabled = true
        // 定位初始化
        mLocClient = LocationClient(this)
        mLocClient!!.registerLocationListener(myListener)
        val option = LocationClientOption()
        // 打开gps
        option.isOpenGps = true
        // 设置坐标类型
        option.locationMode = LocationClientOption.LocationMode.Hight_Accuracy
        option.setCoorType("bd09ll")
        option.setScanSpan(1000)
        mLocClient!!.locOption = option
        mLocClient!!.start()
    }

    override fun onResume() {
        super.onResume()

        //在activity执行onResume时执行mMapView. onResume ()，实现地图生命周期管理
        mMapView!!.onResume()
    }

    override fun onPause() {
        super.onPause()
        //在activity执行onPause时执行mMapView. onPause ()，实现地图生命周期管理
        mMapView!!.onPause()
    }

    override fun onDestroy() {
        // 退出时销毁定位
        mLocClient!!.stop()
        mBaiduMap!!.isMyLocationEnabled = false
        mMapView!!.onDestroy()
        mMapView = null
        super.onDestroy()
        //在activity执行onDestroy时执行mMapView.onDestroy()，实现地图生命周期管理
    }

    //获取个性化地图文件地址
    private fun getCustomStyleFilePath(context: Context, customStyleFileName: String): String? {
        var outputStream: FileOutputStream? = null
        var inputStream: InputStream? = null
        var parentPath: String? = null
        try {
            inputStream = context.assets.open("customConfigdir/$customStyleFileName")
            val buffer = ByteArray(inputStream.available())
            inputStream.read(buffer)
            parentPath = context.filesDir.absolutePath
            val customStyleFile = File("$parentPath/$customStyleFileName")
            if (customStyleFile.exists()) {
                customStyleFile.delete()
            }
            customStyleFile.createNewFile()
            outputStream = FileOutputStream(customStyleFile)
            outputStream.write(buffer)
        } catch (e: IOException) {
            Log.e("CustomMapDemo", "Copy custom style file failed", e)
        } finally {
            try {
                inputStream?.close()
                outputStream?.close()
            } catch (e: IOException) {
                Log.e("CustomMapDemo", "Close stream failed", e)
                return null
            }
        }
        return "$parentPath/$customStyleFileName"
    }

    //定位监听器
    inner class MyLocationListener : BDLocationListener {
        override fun onReceiveLocation(location: BDLocation) {
            // MapView 销毁后不在处理新接收的位置
            if (location == null || mMapView == null) {
                return
            }
            val locData = MyLocationData.Builder()
                .accuracy(location.radius) // 设置定位数据的精度信息，单位：米
                .direction(location.direction) // 此处设置开发者获取到的方向信息，顺时针0-360
                .latitude(23.0540551376)
                .longitude(113.4130708748)
                .build()
            // 设置定位数据, 只有先允许定位图层后设置数据才会生效
            mBaiduMap!!.setMyLocationData(locData)
            if (isFirstLoc) {
                isFirstLoc = false
                val latLng = LatLng(23.0540551376, 113.4130708748)
                val builder = MapStatus.Builder()
                builder.target(latLng).zoom(15.0f)
                mBaiduMap!!.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()))
            }
        }
    }

    private fun replaceFragment(fragment: Fragment) {
        val fragmentManager = supportFragmentManager
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.mainFragment, fragment)
        transaction.commit()
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.getAction()) {
            MotionEvent.ACTION_UP ->
                //设置延时让画面先加载好
                handler.postDelayed(
                    Runnable {
                        UiTool.hideStatusNavigationBar(this, true)
                    }, 3000
                )
        }
        return super.dispatchTouchEvent(ev)
    }

    inline fun <reified T> startActivity(context: Context, block: Intent.() -> Unit) {
        val intent = Intent(context, T::class.java)
        intent.block()
        context.startActivity(intent)
    }
}

